package com.alibaba.citrus.ots.platform.enhance.facade.service;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.platform.enhance.functions.customer.CustomerAddressEntity;
import com.alibaba.citrus.ots.platform.enhance.repository.CustomerAddressRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.model.DubboResult;
import com.alibaba.citrus.ots.platform.enhance.repository.utils.ResultUtils;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.BaselineBatchQueryPlatforms2Request;
import com.epoch.app.bcots.model.dto.BaselineGetEmployeesEsRequest;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByCodes2Request;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByCodes2Response;
import com.epoch.app.bcots.model.dto.GetEmployeeOrganizationsRequest;
import com.epoch.app.bcots.model.dto.OrganizationSDO;
import com.epoch.app.bcots.model.dto.PlatformSDO;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.bcots.service.BcOtsService;
import com.epoch.app.otsplatformenhance.api.customeraddresswrite.dto.CustomerReceivingAddressImportRequest;
import com.epoch.app.otsplatformenhance.api.customeraddresswrite.dto.CustomerReceivingAddressImportResponse;
import com.epoch.app.otsplatformenhance.api.customeraddresswrite.service.CustomerAddressWriteService;
import com.epoch.app.otsplatformenhance.company.model.Company;
import com.epoch.app.otsplatformenhance.company.service.CompanyService;
import com.epoch.app.otsplatformenhance.domain.customer.service.CustomerService;
import com.epoch.app.otsplatformenhance.domain.customeraddress.service.CustomerAddressService;
import com.epoch.app.otsplatformenhance.domain.customersalescope.dto.CustomerSaleScopeLoadListRequest;
import com.epoch.app.otsplatformenhance.domain.customersalescope.model.CustomerSaleScope;
import com.epoch.app.otsplatformenhance.domain.customersalescope.service.CustomerSaleScopeService;
import com.epoch.app.otsplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.otsplatformenhance.model.dto.CustomerQuantity;
import com.epoch.app.otsplatformenhance.model.dto.ImportCustomerAddressSDO;
import com.epoch.app.otsplatformenhance.sdo.CustomerAddressSDO;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Primary
@Service
public class CustomerAddressWriteServiceImpl implements CustomerAddressWriteService {

    private static final Log log = Log.getLogger(CustomerAddressWriteServiceImpl.class);

    @Resource
    private BcOtsService bcOtsService;
    @Resource
    private BaseDataService baseDataService;
    @Resource
    private CustomerAddressRepository customerAddressRepository;
    @Resource
    private EpochMessageService messageService;
    @Resource
    CustomerService customerService;
    @Resource
    CustomerSaleScopeService saleScopeService;
    @Resource
    CustomerAddressService customerAddressService;
    @Resource
    CustomerSaleScopeService customerSaleScopeService;
    @Resource
    CompanyService companyService;


    @Override
    @FacadeInvoker
    public Result<Boolean> editCustomerAddress(CustomerAddressSDO sdo) {
        CustomerAddressEntity addressEntity = CustomerAddressEntity.of(sdo);
        Boolean result = addressEntity.edit();

        try {
            // 编辑客户地址的渠道、部门、负责人的时候，要同步修改
            List<String> idList = Lists.newArrayList(sdo.getId());
            log.info("CustomerAddressWriteServiceImpl_salesPlanAddressChangeMessage{}", JSON.toJSONString(idList));
            Boolean aBoolean = messageService.sendMessage("sales_plan_address_change_message", "CR_SALES_PLAN", "customerAddress_collect", JSON.toJSONString(idList));
        } catch (Exception e) {
            log.error("客户地址分派发送消息异常", e);
        }
        return Result.success(result);
    }


    /**
     * 导入客户收货地址
     *
     * @param customerReceivingAddressImportRequest
     * @return
     */
    @Override
    @FacadeInvoker
    public CustomerReceivingAddressImportResponse customerReceivingAddressImport(CustomerReceivingAddressImportRequest customerReceivingAddressImportRequest) {
        if (Objects.isNull(customerReceivingAddressImportRequest) || org.apache.commons.collections.CollectionUtils.isEmpty(customerReceivingAddressImportRequest.getRequestList())) {
            throw new FacadeException("OTS-01-004-02-16-001");
        }

        List<ImportCustomerAddressSDO> requestList = customerReceivingAddressImportRequest.getRequestList();
        for (ImportCustomerAddressSDO importCustomerAddressSDO : requestList) {
            //判断必填的字段
            if (Strings.isBlank(importCustomerAddressSDO.getId())) {
                importCustomerAddressSDO.setErrorMessage(ErrorMessage.code("OTS-01-004-02-16-009", null).getDisplayErrorMessage());
                continue;
            }
//            if (Strings.isBlank(importCustomerAddressSDO.getOrgSaleDepartmentCode())) {
//                importCustomerAddressSDO.setErrorMessage(ErrorMessage.code("OTS-01-004-02-16-002", null).getDisplayErrorMessage());
//                continue;
//            }
//            if (Strings.isBlank(importCustomerAddressSDO.getOrgSaleChannelCode())) {
//                importCustomerAddressSDO.setErrorMessage(ErrorMessage.code("OTS-01-004-02-16-021", null).getDisplayErrorMessage());
//                continue;
//            }
          /*  if (Strings.isBlank(importCustomerAddressSDO.getPrincipal())) {
                importCustomerAddressSDO.setErrorMessage(ErrorMessage.code("OTS-01-004-02-16-003", null).getDisplayErrorMessage());
                continue;
            }*/

            //根据id查询原数据
            CustomerAddressSDO load = customerAddressRepository.load(importCustomerAddressSDO.getId());
            if (Objects.isNull(load)) {
                importCustomerAddressSDO.setErrorMessage(ErrorMessage.code("OTS-01-004-02-16-011", null).getDisplayErrorMessage());
                continue;
            }

            //电商字段处理,校验非必填 但是如果填了要进行校验
            String commercePlatformName = importCustomerAddressSDO.getCommercePlatform();
            String commercePlatformCode = importCustomerAddressSDO.getCommercePlatformCode();
            if (StringUtils.isNotBlank(commercePlatformName) || StringUtils.isNotBlank(commercePlatformCode)) {
                BaselineBatchQueryPlatforms2Request baselineBatchQueryPlatforms2Request = new BaselineBatchQueryPlatforms2Request();
                if(StringUtils.isNotBlank(commercePlatformCode)){
                    baselineBatchQueryPlatforms2Request.setPlatformCodes(Lists.newArrayList(commercePlatformCode));
                }else{
                    baselineBatchQueryPlatforms2Request.setPlatformNames(Lists.newArrayList(commercePlatformName));
                }
                Result<List<PlatformSDO>> result = baseDataService.baselineBatchQueryPlatforms2(baselineBatchQueryPlatforms2Request);
                if (CollectionUtils.isEmpty(result.getResult())) {
                    importCustomerAddressSDO.setErrorMessage(ErrorMessage.code("OTS-01-004-02-16-024", null).getDisplayErrorMessage());
                    continue;
                }
                PlatformSDO platformSDO = result.getResult().get(0);
                load.setCommercePlatform(platformSDO.getPlatformId());
            }
            if (StringUtils.isNotBlank(importCustomerAddressSDO.getCommerceSellerCode())) {
                load.setCommerceSellerCode(importCustomerAddressSDO.getCommerceSellerCode());
            }
            if (StringUtils.isNotBlank(importCustomerAddressSDO.getCommerceDeliveryCode())) {
                load.setCommerceDeliveryCode(importCustomerAddressSDO.getCommerceDeliveryCode());
            }

            //查询销售负责人信息
            String principalNick = importCustomerAddressSDO.getPrincipal();
            String principalName = importCustomerAddressSDO.getPrincipalName();
            if(StringUtils.isNotBlank(principalNick) || StringUtils.isNotBlank(principalName)) {
                BaselineGetEmployeesEsRequest baselineGetEmployeesEsRequest = new BaselineGetEmployeesEsRequest();
                if(StringUtils.isNotBlank(principalNick)){
                    baselineGetEmployeesEsRequest.setNick(principalNick);
                }else{
                    baselineGetEmployeesEsRequest.setName(principalName);
                }
                DubboResult result = ResultUtils.getBaseLineDubboResult((Map) baseDataService.baselineGetEmployeesEs(baselineGetEmployeesEsRequest));
                List<Map<String, Object>> employeeList = (List) result.getResult();
                if (Objects.isNull(employeeList) || CollectionUtils.isEmpty(employeeList)) {
                    importCustomerAddressSDO.setErrorMessage(ErrorMessage.code("OTS-01-004-02-16-025", null).getDisplayErrorMessage());
                    continue;
                }
                //员工名称查询 es模糊搜索 需要过滤
                if(StringUtils.isNotBlank(baselineGetEmployeesEsRequest.getName())){
                    employeeList = employeeList.stream().filter(x->{
                        Map employeeMap = (Map) x.get("employeeSDO");
                        if(principalName.equals(employeeMap.get("name"))){
                            return true;
                        }else{
                            return false;
                        }
                    }).collect(Collectors.toList());
                }
                Map<String, Object> employeeSDO = employeeList.get(0);
                //获取销售负责人的所属部门、所属渠道
                if (employeeSDO != null) {
                    Map employee = (Map) employeeSDO.get("employeeSDO");
                    load.setPrincipal(employee.get("id").toString());
                    GetEmployeeOrganizationsRequest getEmployeeOrganizationsRequest = new GetEmployeeOrganizationsRequest();
                    getEmployeeOrganizationsRequest.setEmployeeId(employee.get("id").toString());
                    DubboResult result2 = ResultUtils.getDubboResultList((Map)bcOtsService.getEmployeeOrganizations(getEmployeeOrganizationsRequest));
                    List<Map<String, Map<String,Object>>> employeeOrgList = (List) result2.getResult();
                    if (CollectionUtils.isNotEmpty(employeeOrgList)) {
                        //若销售负责人的账号所属组织的组织类型为【销售部门】，则带值销售渠道、销售部门；
                        //若销售负责人的账号所属组织的组织类型为【销售渠道】，则仅带值销售渠道；
                        //若销售负责人的账号所属组织的组织类型为其他，则不带值；
                        Map<String,Object> organization = employeeOrgList.get(0).get("organizationSDO");
                        String orgType = organization.get("type").toString();
                        if(OrganizationTypeEnum.SALES_DEPARTMENT.getCode().toString().equals(orgType)){
                            load.setOrgSaleDepartmentCode(organization.get("id").toString());
                            load.setOrgSaleChannelCode(organization.get("parentId").toString());
                        }else if(OrganizationTypeEnum.SALES_CHANNEL.getCode().toString().equals(orgType)){
                            load.setOrgSaleDepartmentCode("");
                            load.setOrgSaleChannelCode(organization.get("id").toString());
                        }else{
                            load.setOrgSaleDepartmentCode("");
                            load.setOrgSaleChannelCode("");
                        }
                    }
                }
            }
            //修改
            CustomerAddressEntity addressEntity = CustomerAddressEntity.of(load);
            addressEntity.edit();
        }

        try {
            // 编辑客户地址的渠道、部门、负责人的时候，要同步修改
            List<String> idList = requestList.stream().map(ImportCustomerAddressSDO::getId).collect(Collectors.toList());
            log.info("CustomerAddressWriteServiceImpl_salesPlanAddressChangeMessage{}", JSON.toJSONString(idList));
            Boolean aBoolean = messageService.sendMessage("sales_plan_address_change_message", "CR_SALES_PLAN", "customerAddress_collect", JSON.toJSONString(idList));
        } catch (Exception e) {
            log.error("导入客户地址分派发送消息异常", e);
        }

        return CustomerReceivingAddressImportResponse.builder().requestList(requestList).build();
    }

    /**
     * 核对客户数据
     * <p>
     * 1.核对客户档案
     * 2.核对客户售达方
     * 3.核对客户送达方
     *
     * @return
     */
    @Override
    public Result<Map<String, List<CustomerQuantity>>> checkCustomerTools() {
        Map<String, List<CustomerQuantity>> returnData = new HashMap<>();
        try {
            //1.客户档案————根据ope_customer表里的code－客户编码字段判重唯一客户
            Result<List<CustomerQuantity>> customerSummary = customerService.customerSummary();
            //如果 customer为空说明没有 code客户编码数量大于1的数据
            List<CustomerQuantity> customerList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(customerSummary.getResult()) || customerSummary.getTotal() != 0) {
                customerSummary.getResult().stream().forEach(it -> {
                    CustomerQuantity customers = new CustomerQuantity();
                    BeanUtils.copyProperties(it, customers);
                    customerList.add(customers);
                    log.error("CustomerAddressWriteServiceImpl#checkCustomerTools_fail 查询出重复数据:" + JSONObject.toJSONString(customers));
                });
            }
            log.error("CustomerAddressWriteServiceImpl#checkCustomerTools_fail 查询出重复数据:" + customerSummary.getTotal() + "条" + JSONObject.toJSONString(customerList));
            returnData.put("客户档案重复数据", customerList);


        /*2.客户售达方————根据ope_customer_sale_scope表里的（＂customerCode＂＋＂orgSaleOrganizationCode
        ＂＋＂itemGroup＂＋＂channelCode＂）四健合一查询要求唯一*/
            Result<List<CustomerQuantity>> saleScopeSummary = saleScopeService.customerSaleScopeSummary();
            //如果 saleScopeSummary为空说明没有 customer_code,org_sale_organization_code,item_group,channel_code四健合一数量大于1的数据
            List<CustomerQuantity> customerSaleScopeList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(saleScopeSummary.getResult()) || saleScopeSummary.getTotal() != 0) {
                saleScopeSummary.getResult().stream().forEach(it -> {
                    CustomerQuantity customerSaleScope = new CustomerQuantity();
                    BeanUtils.copyProperties(it, customerSaleScope);
                    customerSaleScopeList.add(customerSaleScope);
                    log.error("CustomerAddressWriteServiceImpl#checkCustomerTools_fail 查询出重复数据:" + JSONObject.toJSONString(customerSaleScope));
                });
            }
            log.error("CustomerAddressWriteServiceImpl#checkCustomerTools_fail 查询出重复数据:" + saleScopeSummary.getTotal() + "条" + JSONObject.toJSONString(customerSaleScopeList));
            returnData.put("客户售达方重复数据", customerSaleScopeList);


        /*3.客户送达方————根据ope_customer_address表里的（＂customerCode＂＋＂orgSaleOrganizationCode
         ＂＋＂itemGroup＂＋＂channelCode＂＋＂addressCode＂）五健合一查询要求唯一*/
            Result<List<CustomerQuantity>> customerAddressSummary = customerAddressService.customerAddressSummary();
            //如果 customerAddressSummary为空说明没有 customer_code客户编码数量大于1的数据
            List<CustomerQuantity> customerAddressList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(customerAddressSummary.getResult()) || customerAddressSummary.getTotal() != 0) {
                customerAddressSummary.getResult().stream().forEach(it -> {
                    CustomerQuantity customerAddress = new CustomerQuantity();
                    BeanUtils.copyProperties(it, customerAddress);
                    customerAddressList.add(customerAddress);
                    log.error("CustomerAddressWriteServiceImpl#checkCustomerTools_fail 查询出重复数据:" + JSONObject.toJSONString(customerAddress));
                });
            }
            log.error("CustomerAddressWriteServiceImpl#checkCustomerTools_fail 查询出重复数据:" + customerAddressSummary.getTotal() + "条" + JSONObject.toJSONString(customerAddressList));
            returnData.put("客户送达方重复数据", customerAddressList);


            //4.当客户售达方中　销售组织编码为＂6000＂时，且客户编码等于某一条公司编码，判断该数据里的＂features＂里面是否存在＂仓库＂字段，如没有则该数据记录日志异常
            BaselineGetOrganizationByCodes2Response byCodes2Response = baseDataService.baselineGetOrganizationByCodes2(BaselineGetOrganizationByCodes2Request.builder().ids(Lists.newArrayList("6000")).build());
            if (CollectionUtils.isEmpty(byCodes2Response.getResult())) {
                log.error("CustomerAddressWriteServiceImpl.checkCustomer Tools 查询组织失败，入参为：" + JSONObject.toJSONString("6000"));
            }
            OrganizationSDO organizationSDO = byCodes2Response.getResult().get(0);
            CustomerSaleScopeLoadListRequest customerSaleScopeLoadListRequest = new CustomerSaleScopeLoadListRequest();
            customerSaleScopeLoadListRequest.setLimit(1000);
            customerSaleScopeLoadListRequest.setOrgSaleOrganizationCode(organizationSDO.getId());
            Result<List<CustomerSaleScope>> loadCustomerSaleScopeList = customerSaleScopeService.loadCustomerSaleScopeList(customerSaleScopeLoadListRequest);
            if (CollectionUtils.isEmpty(loadCustomerSaleScopeList.getResult())) {
                log.error("CustomerAddressWriteServiceImpl.checkCustomerTools 查询售达方失败，入参为：" + JSONObject.toJSONString(organizationSDO.getId()));
            }

            Result<List<Company>> listResult = companyService.loadCompanyList();
            //codes 为所有的公司编码
            Set<String> codes = listResult.getResult().stream().map(it -> {
                String code = it.getCode();
                return code;
            }).collect(Collectors.toSet());
            //判断查询出来的客户售达方里的客户编码 是否跟任意一个公司编码所对应
            //customerSaleScopesList包含了  客户编码与任意一个公司编码相同的数据
            List<CustomerSaleScope> customerSaleScopesList = new ArrayList<>();
            loadCustomerSaleScopeList.getResult().stream().forEach(it -> {
                if (codes.contains(it.getCustomerCode())) {
                    customerSaleScopesList.add(it);
                }
            });

            //判断剩余数据中 features中是否包含 storeHouse(仓库)字段
            if (CollectionUtils.isEmpty(customerSaleScopesList)) {
                log.error("CustomerAddressWriteServiceImpl.checkCustomerTools 没有客户编码与任意公司编码相同的数据");
            }
            List<CustomerQuantity> customerSaleScopeAbnormalList = new ArrayList<>();
            for (CustomerSaleScope customerSaleScope : customerSaleScopesList) {
                JSONObject jsonObject = JSONObject.parseObject(customerSaleScope.getFeatures());
                if (!jsonObject.containsKey("storeHouse")) {
                    //如果该数据中不包含  storeHouse  则进行日志记录
                    CustomerQuantity customerQuantity = new CustomerQuantity();
                    BeanUtils.copyProperties(customerSaleScope, customerQuantity);
                    customerSaleScopeAbnormalList.add(customerQuantity);
                    log.error("CustomerAddressWriteServiceImpl.checkCustomerTools 该数据Features中不包含storeHouse" + JSONObject.toJSONString(customerSaleScope));
                }
            }
            returnData.put("客户售达方仓库异常数据", customerSaleScopeAbnormalList);

        } catch (Exception e) {
            log.info("CustomerAddressWriteServiceImpl#checkCustomerTools方法查询错误", e);
        }
        return Result.success(returnData);
    }

}
